/* * Copyright 2008-2012 Xebia and the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package fr.xebia.workshop.nginx; import java.util.Iterator; import java.util.List; import java.util.Map; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.services.ec2.AmazonEC2; import com.amazonaws.services.ec2.AmazonEC2Client; import com.amazonaws.services.ec2.model.CreateTagsRequest; import com.amazonaws.services.ec2.model.Instance; import com.amazonaws.services.ec2.model.InstanceType; import com.amazonaws.services.ec2.model.RunInstancesRequest; import com.amazonaws.services.ec2.model.Tag; import com.amazonaws.services.route53.AmazonRoute53; import com.amazonaws.services.route53.AmazonRoute53Client; import com.amazonaws.services.route53.model.GetHostedZoneRequest; import com.amazonaws.services.route53.model.HostedZone; import com.google.common.collect.Maps; import fr.xebia.cloud.amazon.aws.tools.AmazonAwsUtils; import fr.xebia.cloud.cloudinit.CloudInitUserDataBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author <a href="mailto:cleclerc@xebia.fr">Cyrille Le Clerc</a> * @author <a href="mailto:slemesle@xebia.fr">Séven Le Mesle</a> */ public class CreateNginxProxyServers implements Runnable { private final Logger logger = LoggerFactory.getLogger(getClass()); private static final String WWW_NGINX = "www-nginx-"; private static final String CLOUD_CONFIG_FILE_PATH = "fr/xebia/workshop/nginx/cloud-config-amzn-linux-nginx.txt"; private AmazonEC2 ec2; private AmazonRoute53 route53; private WorkshopInfrastructure workshopInfrastructure; public static void main(String[] args) { AWSCredentials awsCredentials = AmazonAwsUtils.loadAwsCredentials(); AmazonEC2 ec2 = new AmazonEC2Client(awsCredentials); ec2.setEndpoint("ec2.eu-west-1.amazonaws.com"); AmazonRoute53 route53 = new AmazonRoute53Client(awsCredentials); WorkshopInfrastructure workshopInfrastructure = new WorkshopInfrastructure() .withTeamIdentifiers("1"/*, "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"*/) .withAwsAccessKeyId(awsCredentials.getAWSAccessKeyId()) .withAwsSecretKey(awsCredentials.getAWSSecretKey()) .withKeyPairName("nginx-workshop") .withBeanstalkNotificationEmail("slemesle@xebia.fr"); CreateNginxProxyServers job = new CreateNginxProxyServers(ec2, route53, workshopInfrastructure); job.run(); /* List<Reservation> reservations = ec2.describeInstances(new DescribeInstancesRequest().withInstanceIds("i-7741eb3f")).getReservations(); Instance instance = Iterables.getOnlyElement(Iterables.getOnlyElement(reservations).getInstances()); Map<String, Instance> instancesByTeamId = Collections.singletonMap("clc", instance); job.bindInstancesToDnsCnames(instancesByTeamId, route53); */ } private HostedZone hostedZone; public CreateNginxProxyServers(AmazonEC2 ec2, AmazonRoute53 route53, WorkshopInfrastructure workshopInfrastructure) { this.ec2 = ec2; this.route53 = route53; this.workshopInfrastructure = workshopInfrastructure; this.hostedZone = route53.getHostedZone(new GetHostedZoneRequest("Z28O5PDK1WPCSR")).getHostedZone(); } private List<Instance> createNewInstances(AmazonEC2 ec2, WorkshopInfrastructure infra) { String userData = CloudInitUserDataBuilder.start().addCloudConfigFromFilePath(CLOUD_CONFIG_FILE_PATH).buildBase64UserData(); int instanceCount = infra.getTeamCount(); RunInstancesRequest runInstancesRequest = new RunInstancesRequest() // .withInstanceType(InstanceType.T1Micro.toString()) // .withImageId(AmazonAwsUtils.AMI_AMZN_LINUX_EU_WEST_2012_09) // .withMinCount(instanceCount) // .withMaxCount(instanceCount) // .withSecurityGroupIds("accept-all") // .withKeyName(infra.getKeyPairName()) // .withUserData(userData); List<Instance> instances = AmazonAwsUtils.reliableEc2RunInstances(runInstancesRequest, ec2); if (instances.size() != instanceCount) { logger.warn("Unexpected number of instances created: {} instead of {} expected", instances.size(), instanceCount); } return instances; } protected Map<String, Instance> associateInstancesToTeamIds(List<Instance> instances, List<String> teamIdentifiers) { Map<String, Instance> instancesByTeamId = Maps.newHashMap(); Iterator<String> teamsIdIterator = teamIdentifiers.iterator(); for (Instance instance : instances) { instancesByTeamId.put(teamsIdIterator.next(), instance); } return instancesByTeamId; } protected void tagInstances(Map<String, Instance> instancesByTeamId, AmazonEC2 ec2) { for (Map.Entry<String, Instance> entry : instancesByTeamId.entrySet()) { String identifier = entry.getKey(); Instance instance = entry.getValue(); String serverName = WWW_NGINX + identifier; logger.info("Tagging {} - {}", serverName, instance.getInstanceId()); CreateTagsRequest createTagsRequest = new CreateTagsRequest() // .withResources(instance.getInstanceId()) // .withTags( // new Tag("Name", serverName), // new Tag("TeamIdentifier", identifier), // new Tag("Workshop", "nginx"), // new Tag("Role", "nginx-proxy"), // new Tag("CNAME", buildCname(identifier))// ); AmazonAwsUtils.createTags(instance, createTagsRequest, ec2); } } public void run() { AmazonAwsUtils.terminateInstancesByWorkshop("nginx", ec2); List<Instance> instances = createNewInstances(ec2, workshopInfrastructure); Map<String, Instance> instancesByTeamId = associateInstancesToTeamIds(instances, workshopInfrastructure.getTeamIdentifiers()); tagInstances(instancesByTeamId, ec2); bindInstancesToDnsCnames(instancesByTeamId, route53); } protected void bindInstancesToDnsCnames(Map<String, Instance> instancesByTeamId, AmazonRoute53 route53) { logger.info("Process {}", hostedZone); Map<String, Instance> cnamesToInstance = Maps.newHashMap(); for (Map.Entry<String, Instance> entry : instancesByTeamId.entrySet()) { String teamId = entry.getKey(); Instance instance = entry.getValue(); String cname = buildCname(teamId); cnamesToInstance.put(cname, instance); } AmazonAwsUtils.deleteCnameIfExist(cnamesToInstance.keySet(), hostedZone, route53); AmazonAwsUtils.createCnamesForInstances(cnamesToInstance, hostedZone, route53); logger.info("Nginx servers creation SUCCESSFUL"); } protected String buildCname(String teamId) { return WWW_NGINX + teamId + "." + hostedZone.getName(); } }